﻿using FluorineFx.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;


namespace lxwmvc
{
    /// <summary>
    /// 功能:转换类，处理各种类型之间的转换
    /// [09.4.10 lxw]<para />
    /// </summary>
    public static class extensionhelper
    {
        /// <summary>
        /// 功能:转换objValue为int
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="iDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回0</returns>
        public static int toint32(this object objValue, int iDefault = 0, bool throwE = false)
        {
            try
            {
                int t;
                if (Int32.TryParse(objValue.ToString().Split('.')[0], out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return iDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return iDefault;
            }
        }

        /// <summary>
        /// 转换T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T toT<T>(this object obj)
        {
            if(obj == null) return default(T);
            
            Type t = typeof(T);
            if (t == typeof(int))
                return (T)Convert.ChangeType(obj.toint32(), t);
            else if (t == typeof(decimal))
                return (T)Convert.ChangeType(obj.todecimal(), t);
            else if (t == typeof(string))
                return (T)Convert.ChangeType(obj.tostr(), t);
            else if (t == typeof(DateTime))
                return (T)Convert.ChangeType(obj.todatetime(), t);

            //http://www.csharpwin.com/csharpspace/12851r5551.shtml
            if (!typeof(T).IsGenericType)
            {
                return (T)Convert.ChangeType(obj, typeof(T));
            }
            Type genericTypeDefinition = typeof(T).GetGenericTypeDefinition();
            if (genericTypeDefinition == typeof(Nullable<>))
            {
                if (obj == null || obj.tostr() == "") return default(T);
                return (T)Convert.ChangeType(obj, Nullable.GetUnderlyingType(typeof(T)));
            }


            throw new InvalidCastException(string.Format("无效的类型转换 \"{0}\" to type \"{1}\".",
                obj.GetType().FullName,
                typeof(T).FullName));
        }

        /// <summary>
        /// 功能:转换objValue为uint
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="iDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回0</returns>
        public static uint touint32(this object objValue, uint iDefault = 0, bool throwE = false)
        {
            try
            {
                uint t;
                if (UInt32.TryParse(objValue.ToString().Split('.')[0], out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return iDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return iDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为Decimal
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="dDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回0</returns>
        public static decimal todecimal(this object objValue, decimal dDefault = 0, bool throwE = false)
        {
            try
            {
                decimal t;
                if (decimal.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return dDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return dDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue byte[]为Base64String
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="sDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回空字符串</returns>
        public static string tobase64string(this object objValue, string sDefault = "", bool throwE = false)
        {
            try
            {
                return Convert.ToBase64String((byte[])objValue);
            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return sDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为bool
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="bDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回false</returns>
        public static bool toboolean(this object objValue, bool bDefault = false, bool throwE = false)
        {
            try
            {
                bool t;
                if (bool.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return bDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return bDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为Byte
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="bDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回0</returns>
        public static byte tobyte(this object objValue, byte bDefault = 0, bool throwE = false)
        {
            try
            {
                byte t;
                if (byte.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return bDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return bDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为Char
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="cDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 '0'</returns>
        public static char tochar(this object objValue, char cDefault = '0', bool throwE = false)
        {
            try
            {
                char t;
                if (char.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return cDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return cDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为DateTime
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="sDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 '1900-1-1'的日期</returns>
        public static DateTime todatetime(this object objValue, string sDefault = "1900-1-1", bool throwE = false)
        {
            try
            {
                return Convert.ToDateTime(objValue.ToString());
            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return Convert.ToDateTime(sDefault);
            }
        }

        /// <summary>
        /// 功能:转换objValue为Char
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="dDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 0</returns>
        public static double todouble(this object objValue, double dDefault = 0, bool throwE = false)
        {
            try
            {
                double t;
                if (double.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return dDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return dDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为Int16
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="sDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 0</returns>
        public static short toint16(this object objValue, short sDefault = 0, bool throwE = false)
        {
            try
            {
                short t;
                if (short.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return sDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return sDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为uInt16
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="sDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 0</returns>
        public static ushort touint16(this object objValue, ushort sDefault = 0, bool throwE = false)
        {
            try
            {
                ushort t;
                if (ushort.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return sDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return sDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为Int64
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="lDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 0</returns>
        public static long toint64(this object objValue, long lDefault = 0, bool throwE = false)
        {
            try
            {
                long t;
                if (long.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return lDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return lDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为UInt64
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="lDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 0</returns>
        public static ulong touint64(this object objValue, ulong lDefault = 0, bool throwE = false)
        {
            try
            {
                ulong t;
                if (ulong.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return lDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return lDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为sbyte
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="sDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 0</returns>
        public static sbyte tosbyte(this object objValue, sbyte sDefault = 0, bool throwE = false)
        {
            try
            {
                sbyte t;
                if (sbyte.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return sDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return sDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为Float
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="fDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回 0</returns>
        public static float tosingle(this object objValue, float fDefault = 0, bool throwE = false)
        {
            try
            {
                float t;
                if (float.TryParse(objValue.ToString(), out t))
                    return t;
                else
                {
                    if (throwE) throw new Exception("转换失败:" + objValue.tostr());
                    return fDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return fDefault;
            }
        }

        /// <summary>
        /// 功能:转换objValue为String,主要区别于ToString， ToStr为安装转换，可以用ToStr代替toString,string a = null;string b = a.ToStr();string c = a.ToString();
        /// [11-03-10 09:23  周四 lxw]<para />
        /// [11-03-09 10:10  周三 lxw]<para />
        /// </summary>
        /// <param name="objValue">源对象</param>
        /// <param name="sDefault">默认值</param>
        /// <param name="throwE">是否抛出异常</param>
        /// <returns>如果错误,返回""</returns>
        public static string tostr(this object objValue, string sDefault = "", bool throwE = false)
        {
            try
            {
                return objValue.ToString();
            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return sDefault;
            }
        }

        /// <summary>
        /// 判断对象是否为空 IsNullOrEmpty
        /// </summary>
        /// <param name="strValue">string对象</param>
        /// <returns></returns>
        public static bool isnull(this string strValue)
        {
            return string.IsNullOrEmpty(strValue);
        }

        /// <summary>
        /// 判断对象不为空 ！IsNullOrEmpty
        /// </summary>
        /// <param name="strValue">string对象</param>
        /// <returns></returns>
        public static bool isnotnull(this string strValue)
        {
            return !string.IsNullOrEmpty(strValue);
        }

        /// <summary>
        /// 安全字符串
        /// </summary>
        /// <param name="objValue"></param>
        /// <param name="sDefault"></param>
        /// <param name="throwE"></param>
        /// <returns></returns>
        public static string tosafe(this object objValue, string sDefault = "", bool throwE = false)
        {
            try
            {
                return objValue.ToString().Replace("'","''");
            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return sDefault;
            }
        }

        /// <summary>
        /// 去掉小数点
        /// </summary>
        /// <param name="objValue"></param>
        /// <param name="sDefault"></param>
        /// <param name="throwE"></param>
        /// <returns></returns>
        public static string toshuzi(this object objValue, string sDefault = "", bool throwE = false)
        {
            try
            {
                return objValue.tostr().Split('.')[0];
            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return sDefault;
            }
        }

        /// <summary>
        /// 把list supermodel转换成javascript array
        /// </summary>
        /// <param name="objValue"></param>
        /// <returns></returns>
        public static JavaScriptArray tojson(this List<supermodel> objValue)
        {
            try
            {
                JavaScriptArray lst = new JavaScriptArray();
                foreach (supermodel sm in objValue)
                {
                    JavaScriptObject jso = new JavaScriptObject();
                    foreach (string key in sm.Keys)
                    {
                        jso[key.ToLower()] = sm[key] == DBNull.Value ? "" : (sm[key]??"");
                    }
                    lst.Add(jso);
                }
                return lst; 
            }
            catch (Exception error)
            {
                dataloger.fatal("tojson this List<supermodel> objValue", error);
                return null;
            }
        }


        static int DateTimeToStamp(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }

        /// <summary>
        /// 把this IEnumerable 转换成javascriptarray
        /// </summary>
        /// <param name="objValue"></param>
        /// <returns></returns>
        public static JavaScriptArray tojson(this IEnumerable<dynamic> objValue)
        {
            try
            {
                JavaScriptArray lst = new JavaScriptArray();

                foreach (var r in objValue)
                {
                    if (r is supermodel)
                    {
                        JavaScriptObject jso = new JavaScriptObject();
                        var c = r as supermodel;

                        foreach (string key in c.Keys)
                        {
                            var obj = c[key];
                            if(obj.GetType() == typeof(DateTime))
                                jso[key.ToLower()] = DateTimeToStamp((DateTime)c[key]);
                            else
                                jso[key.ToLower()] = c[key];
                        }
                        lst.Add(jso);
                    }
                    else
                    {
                        JavaScriptObject jso = new JavaScriptObject();
                        var c = r as IDictionary<String, Object>;

                        foreach (string key in c.Keys)
                        {
                            var obj = c[key];
                            if (obj.GetType() == typeof(DateTime))
                                jso[key.ToLower()] = DateTimeToStamp((DateTime)c[key]);
                            else
                                jso[key.ToLower()] = c[key];
                        }
                        lst.Add(jso);
                    }
                }
                return lst;
            }
            catch (Exception error)
            {
                dataloger.fatal("JavaScriptArray tojson(this IEnumerable<dynamic> objValue)", error);
                return null;
            }
        }

        /// <summary>
        /// 循环foreach
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="objValue"></param>
        /// <param name="fun"></param>
        public static void Foreach<T>(this IEnumerable<T> objValue,Action<T> fun)
        {
            foreach (T t in objValue)
            {
                fun(t);
            }
        }

        /// <summary>
        /// 把javascriptarray转换成 list  supermodel
        /// </summary>
        /// <param name="objValue"></param>
        /// <returns></returns>
        public static List<supermodel> tojson(this JavaScriptArray objValue)
        {
            try
            {
                List<supermodel> sms = new List<supermodel>();
                foreach (JavaScriptObject jso in objValue)
                {
                    supermodel sm = supermodel.create();
                    foreach (string key in jso.Keys)
                    {
                        sm[key.ToLower()] = jso[key] ?? "";
                    }
                    sms.Add(sm);
                }
                return sms;
            }
            catch (Exception error)
            {
                dataloger.fatal("tojson this JavaScriptArray objValue", error);
                return null;
            }
        }


        
        /// <summary>
        /// 把supermodel转换成javascriptobject
        /// </summary>
        /// <param name="sm"></param>
        /// <returns></returns>
        public static JavaScriptObject tojson(this supermodel sm)
        {
            try
            {
                JavaScriptObject jso = new JavaScriptObject();
                foreach (string key in sm.Keys)
                {
                    jso[key.ToLower()] = sm[key] == DBNull.Value ? "" : (sm[key] ?? "");
                }

                return jso;
            }
            catch (Exception error)
            {
                dataloger.fatal("public static JavaScriptObject tojson(this supermodel sm)", error);
                return null;
            }
        }

        /// <summary>
        /// 把javascriptobject 转换成 supermodel
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public static supermodel tosm(this JavaScriptObject json)
        {
            try
            {
                supermodel sm = supermodel.create();
                foreach (string key in json.Keys)
                {
                    sm[key.ToLower()] = json[key] ?? "";
                }

                return sm;
            }
            catch (Exception error)
            {
                dataloger.fatal(" public static supermodel tosm(this JavaScriptObject json)", error);
                return null;
            }
        }

        //public static DataTable totable(this IEnumerable<dynamic> obj)
        //{
        //    DataTable systableinfo = null;
        //    bool bColumn = false;
        //    foreach (var r in obj)
        //    {
        //        if (!bColumn)
        //        {
        //            systableinfo = new DataTable();
        //            bColumn = true;
        //            var c = ((string[])((r as IDictionary<String, Object>).Keys));
        //            foreach (string s in c)
        //                systableinfo.Columns.Add(s);
        //        }

        //        {
        //            var row = systableinfo.NewRow();
        //            var c = ((object[])((r as IDictionary<String, Object>).Values));
        //            int i = 0;
        //            foreach (object s in c)
        //                row[i++] = s.tostr();
        //            systableinfo.Rows.Add(row);
        //        }
        //    }

        //    return systableinfo;
        //}


        ///// <summary>
        ///// 时间戳转为C#格式时间
        ///// </summary>
        ///// <param name="objValue"></param>
        ///// <param name="sDefault"></param>
        ///// <param name="throwE"></param>
        ///// <returns></returns>
        //public static DateTime toUTCTime(this object objValue, string sDefault = "1900-1-1", bool throwE = false)
        //{
        //    try
        //    {
        //        DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
        //        long lTime = long.Parse(objValue + "0000000");
        //        TimeSpan toNow = new TimeSpan(lTime);
        //        return dtStart.Add(toNow);
        //    }
        //    catch (Exception error)
        //    {
        //        if (throwE) throw error;
        //        return Convert.ToDateTime(sDefault);
        //    }
        //}

        ///// <summary>
        /////  DateTime时间格式转换为Unix时间戳格式
        ///// </summary>
        ///// <param name="objValue"></param>
        ///// <param name="iDefault"></param>
        ///// <param name="throwE"></param>
        ///// <returns></returns>
        //public static int toUTC(this object objValue, int iDefault = 0, bool throwE = false)
        //{
        //    try
        //    {
        //        DateTime time = Convert.ToDateTime(objValue.ToString());
        //        return (int)((time.Ticks - 621355968000000000) / 10000000 - 8 * 60 * 60);
        //    }
        //    catch (Exception error)
        //    {
        //        if (throwE) throw error;
        //        return iDefault;
        //    }

        //}

        ///// <summary>
        ///// c# DateTime时间格式转换为Unix时间戳格式  
        ///// </summary>
        ///// <param name="time"></param>
        ///// <returns></returns>
        //public static int toUnixTime(this DateTime time)
        //{
        //    int intResult = 0;
        //    DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
        //    intResult = Convert.ToInt32((time - startTime).TotalSeconds);
        //    return intResult;
        //}

        ///// <summary>
        ///// 根据2个字符串 截取字符串
        ///// </summary>
        ///// <param name="objValue">源字符串</param>
        ///// <param name="indexStr">开始字符串</param>
        ///// <param name="lastStr">结束字符串</param>
        ///// <param name="iDefault">错误返回</param>
        ///// <param name="throwE">是否抛出错误</param>
        ///// <returns></returns>
        //public static string subString(this string objValue, string indexStr = "", string lastStr = "", string iDefault = "", bool throwE = false)
        //{
        //    try
        //    {
        //        int index = objValue.IndexOf(indexStr);
        //        if (lastStr != "" && index > -1) 
        //        { 
        //            objValue = objValue.Remove(0, index); 
        //            index = objValue.IndexOf(indexStr); 
        //        }
        //        int last = objValue.IndexOf(lastStr);
        //        last = last == 0 ? objValue.Length : last;
        //        if (index > -1 && last > -1)
        //        {
        //            objValue = objValue.Substring(index + indexStr.Length, last - (index + indexStr.Length));
        //            return objValue;
        //        }
        //        else
        //        {
        //            return iDefault;
        //        }

        //    }
        //    catch (Exception error)
        //    {
        //        if (throwE) throw error;
        //        return iDefault;
        //    }
        //}
    }
}
